package ua.dogar.vectors;

import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import ua.dogar.exceptions.IncompatibleVectorSizesException;
import ua.dogar.exceptions.VectorIndexOutOfBoundsException;
import ua.dogar.patterns.Observer;



public class JLinkedListVector implements Vector {
	private List<Double> vector;
	public JLinkedListVector() {
		vector = new LinkedList<Double>();
	}

	public JLinkedListVector(double...values) {
		this();
		for(int i = 0 ;i<values.length;i++)
		vector.add(values[i]);
	}

	@Override
	public double getElement(int index) {
		if(index<0 || index>getLength()) throw new VectorIndexOutOfBoundsException(index);
		return vector.get(index);
	}

	@Override
	public void setElement(double value, int index) {
		if(index<0 || index>getLength()) throw new VectorIndexOutOfBoundsException(index);
		vector.set(index, value);
	}

	@Override
	public int getLength() {
		return vector.size();
	}

	@Override
	public void setElementsFromArray(double[] arr) throws IncompatibleVectorSizesException{
		if(arr!=null){
		if(arr.length!=getLength()) throw new IncompatibleVectorSizesException();
		for (int i = 0; i < arr.length; i++) {
			setElement(arr[i], i);
		}
		}
	}

	@Override
	public void setElementsFromVector(Vector v) throws IncompatibleVectorSizesException{
		if(v!=null){
			if(v.getLength()!=getLength()) throw new IncompatibleVectorSizesException();
		for (int i = 0; i < v.getLength(); i++)
			setElement(v.getElement(i), i);
		}
	}

	@Override
	public Vector mulVector(int num) {
		for (int i = 0; i < getLength(); i++)
			setElement(getElement(i) * num, i);
		return this;

	}

	@Override
	public void addVector(Vector v) throws IncompatibleVectorSizesException{
		if(v!=null){
			if(v.getLength()!=getLength()) throw new IncompatibleVectorSizesException();
			for (int i = 0; i < v.getLength(); i++)
				setElement(getElement(i) + v.getElement(i), i);
	
		}
	}
	public void clear(){
		vector.clear();
	}
	@Override
	public boolean compare(Vector v) {
		if (v.getLength() == getLength()) {
			for (int i = 0; i < v.getLength(); i++)
				if (getElement(i) != v.getElement(i))
					return false;
			return true;
		} else
			return false;
	}
	@Override
	protected Object clone() throws CloneNotSupportedException {
		JLinkedListVector clone = (JLinkedListVector) super.clone();
		clone.clear();
		for(int i =0;i<this.getLength();i++){
			clone.setElement(getElement(i),i);
		}
		return clone;
	}
	@Override
	public int hashCode() {
		int result = 0;
		for (int i = 0; i < getLength(); i++) {
			long bits = Double.doubleToRawLongBits(getElement(i));
			result ^= ((int) (bits & 0x00000000FFFFFFFFL))
					^ ((int) ((bits & 0xFFFFFFFF00000000L)));
		}
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (obj instanceof Vector) {
			Vector temp = (Vector) obj;
			if (temp.getLength() == getLength()) {
				for (int i = 0; i < getLength(); i++)
					if (temp.getElement(i) != this.getElement(i))
						return false;
				return true;
			}
		}
		return false;
	}
	@Override
	public String toString() {
		StringBuffer stringOut = new StringBuffer();
		stringOut.append("JLinkdListVector [vector=");
		stringOut.append(vector.toString());
		stringOut.append("]");
		return stringOut.toString();
	}
	@Override
	public Iterator<Double> iterator() {
		return vector.iterator();
	}

	@Override
	public void registerObserver(Observer o) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void removeObserver(Observer o) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void notifyObservers(int index) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void notifyObservers() {
		// TODO Auto-generated method stub
		
	}

}
